package cn.ai.shoes.core.filter;

import cn.ai.shoes.common.exception.ServiceException;
import cn.ai.shoes.common.pojo.entity.CommonResult;
import cn.ai.shoes.core.config.DBUserDetailsManager;
import cn.ai.shoes.core.utils.JwtUtils;

import com.alibaba.fastjson2.JSON;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.io.PrintWriter;

import static cn.ai.shoes.common.exception.constant.GlobalErrorCodeConstants.TOKEN_VERIFY_FAIL;


public class JWTAuthenticationFilter extends OncePerRequestFilter {

    @Resource
    private DBUserDetailsManager dBUserDetailsManager;


    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 获取 authHeader
        String authHeader = request.getHeader(JwtUtils.getTokenHeader());
        System.out.println("[JWTAuthenticationFilter] 请求路径: " + request.getRequestURI());
        System.out.println("[JWTAuthenticationFilter] Authorization头: " + authHeader);
        // 判断 authHeader 是否为空和是否以 jwtTokenUtil.TOKEN_PREFIX 开头
        if (StringUtils.hasText(authHeader) && authHeader.startsWith(JwtUtils.getTokenPrefix())) {
            try {
                // 截取token
                String authToken = authHeader.substring(JwtUtils.getTokenPrefix().length());
                // 解析authHeader，获取 username
                String username = JwtUtils.getUserNameFromToken(authToken);
                System.out.println("[JWTAuthenticationFilter] 解析出的username: " + username);
                // 判断 username 是否为空和 SecurityContextHolder 是否为空
                if (StringUtils.hasText(username) && SecurityContextHolder.getContext().getAuthentication() == null) {
                    // 通过DBUserDetailsManager获取UserDetails
                    UserDetails userDetails = dBUserDetailsManager.loadUserByUsername(username);
                    if (userDetails == null) {
                        throw new ServiceException(TOKEN_VERIFY_FAIL);
                    }
                    // token是否有效
                    if (JwtUtils.verifyToken(authToken,userDetails)) {
                        // 将User 封装到 securityContextHolder。 封装到securityContextHolder以后，其他过滤器就不会在拦截
                        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken
                                (userDetails, null, userDetails.getAuthorities());
                        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                        System.out.println("[JWTAuthenticationFilter] SecurityContextHolder已设置: " + authenticationToken.getPrincipal());
                    } else {
                        System.out.println("[JWTAuthenticationFilter] token校验失败");
                    }
                } else {
                    System.out.println("[JWTAuthenticationFilter] username为空或SecurityContextHolder已有认证");
                }
            } catch (Exception e) {
                // 打印异常信息
                System.out.println("[JWTAuthenticationFilter] 解析token异常: " + e.getMessage());
                e.printStackTrace();
            }
        } else {
            System.out.println("[JWTAuthenticationFilter] Authorization头缺失或格式不正确");
        }
        filterChain.doFilter(request, response);
    }
}
